package com.kent.hellokotlin.bBasic

fun main() {
    fooTemplate()
}

//数字
fun fooNum() {
    val one = 1 // Int
    val threeBillion = 3000000000 // Long
    val oneLong = 1L // Long
    val oneByte: Byte = 1

    val pi = 3.14 // Double
    val e = 2.7182818284 // Double
    val eFloat = 2.7182818284f // Float，实际值为 2.7182817
}

fun printDouble(d: Double) {
    println(d)
}

fun testPrintDouble() {
    val i = 1
    val d = 1.1
    val f = 1.1f

    printDouble(d)
    //printDouble(i) // 错误：类型不匹配
    //printDouble(f) // 错误：类型不匹配
}


//字面常量
//数字字面值中的下划线（自 1.1 起）
fun numWithLine() {
    val oneMillion = 1_000_000
    val creditCardNumber = 1234_5678_9012_3456L
    val socialSecurityNumber = 999_99_9999L
    val hexBytes = 0xFF_EC_DE_5E
    val bytes = 0b11010010_01101001_10010100_10010010
}

//表示方式
//在 Java 平台数字是物理存储为 JVM 的原生类型，除非我们需要一个可空的引用（如 Int?）或泛型。 后者情况下会把数字装箱。
//
//注意数字装箱不一定保留同一性
fun fooBox() {
    val a = 1000;
    val boxA: Int? = a
    val anotherBoxA: Int? = a
    println(boxA === anotherBoxA) // 注意数字装箱不一定保留同一性
    println(boxA == anotherBoxA) // 另一方面，它保留了相等性
}

//显式转换
fun fooCastValue() {
    //因此较小的类型不能隐式转换为较大的类型。 这意味着在不进行显式转换的情况下我们不能把 Byte 型值赋给一个 Int 变量。
    val b: Byte = 1 // OK, 字面值是静态检测的
    //val i: Int = b // 错误
    val i: Int = b.toInt() // OK：显式拓宽

    //缺乏隐式类型转换很少会引起注意，因为类型会从上下文推断出来，而算术运算会有重载做适当转换，例如：
    val l: Long = 1L + i // Long + Int => Long
}

//整数除法
fun fooDivision() {
    //请注意，整数间的除法总是返回整数。会丢弃任何小数部分。例如：
    val x = 5 / 2
    //println(x == 2.5) // ERROR: Operator '==' cannot be applied to 'Int' and 'Double'
    println(x == 2)
    //对于任何两个整数类型之间的除法来说都是如此。
    val y = 5L / 2
    println(y == 2L)
    //如需返回浮点类型，请将其中的一个参数显式转换为浮点类型。
    val z = 5 / 2.toDouble()
    println(z == 2.5)
}

//字符
fun digitalCharToInt(c: Char): Int {
    if (c !in '0'..'9') throw IllegalArgumentException("Out of Range")
    return c.toInt() - '0'.toInt()
}

//数组
fun fooArray() {
    // 创建一个 Array<String> 初始化为 ["0", "1", "4", "9", "16"]
    val asc = Array(5) { i -> (i * i).toString() }
    asc.forEach { println(it) }

    //原生类型数组
    val x = intArrayOf(1, 2, 3)
    x[0] = x[1] + x[2]

    var arr = IntArray(5)
    arr = IntArray(5) { 6 }
    arr = IntArray(5) { i -> i * 6 }

}

//字符串
fun fooStr() {
    val str = "String"
    for (c in str) {
        println(c)
    }

    //可以用 + 操作符连接字符串。这也适用于连接字符串与其他类型的值， 只要表达式中的第一个元素是字符串
    val s0 = "abc" + 1
    //val s = 1 + "abc" // 错误


    //转义字符串
    val s = "Hello, world!\n"//可以有转义字符

    //原始字符串
    val s1 = """
        what 
         is 
          this
    """
    println(s1)
    println("---------------------------------------------------------------------------------------")
    val s2 = """
        what 
         is 
          this
    """.trimIndent()
    println(s2)
    println("---------------------------------------------------------------------------------------")
    val s3 = """
        |what 
         |is 
          |this
    """.trimMargin()
    println(s3)
    println("---------------------------------------------------------------------------------------")
}

//字符串模板
fun fooTemplate() {
    val i = 10
    println("i = $i") // 输出“i = 10”

    val s = "abc"
    println("$s.length is ${s.length}") // 输出“abc.length is 3”

    //val price1 = "$symbol" // $后面不能紧跟着字母 需要使用如下方法
    val price1 = "${'$'}symbol"

    println(price1)
}
